#ifndef TC_CHANDEOSCILLATOR_HPP
#define TC_CHANDEOSCILLATOR_HPP

/** \file ChandeOscillator.hpp
 * Definition of the function template ChandeOscillator.
 *
 * (c) Copyright 2003-2006 by Semih Cemiloglu
 * All rights reserved, see COPYRIGHT file for details.
 *
 * $Id: ChandeOscillator.hpp 119 2006-06-21 04:57:25Z semihc $
 *
 *
 */


#include <vector>
#include "TA.hh"
#include "DBC.hpp"
#include "CircArray.hpp"

namespace TC {

  //! Chande Momentum Oscillator function
  TC_EXPORT template <typename InputIterator,
                      typename OutputIterator,
                      class Adaptor>
  void ChandeOscillator(InputIterator fromPos,
			InputIterator fromEnd,
			OutputIterator toPos,
			const unsigned period,
			const Adaptor adaptor)
  {
    TC_PRE_CONDITION(period > 0);

    // Close, previous close
    register typename Adaptor::Price_t cls, prevCls;
    // Initial values
    cls = prevCls = adaptor(*fromPos);
    // Change of prices
    std::vector<TAfp_t> change_line;
    // Su = Summation of difference between today's close and 
    // yesterday's close on up days.
    // Sd = Summation of difference between today's close and
    // yesterday's close on down days
    register TAfp_t su, sd;
    CircArray<TAfp_t> su_array(period);
    CircArray<TAfp_t> sd_array(period);

    for(; fromPos!=fromEnd; ++fromPos) {
      cls = adaptor(*fromPos);
      change_line.push_back(cls - prevCls);
      prevCls = cls;
    } // end for

    for(unsigned i=0; i<change_line.size(); ++i) { 
      if(change_line[i] >= 0) {
	su_array.push(change_line[i]);
	sd_array.push(0);
      }
      else {
	su_array.push(0);
	sd_array.push(change_line[i]);
      }
      su = su_array.sum();
      sd = sd_array.sum();
      if(su==sd)
	*toPos++ = 0; // Avoid division by zero
      else
	*toPos++ = ((su+sd)/(su-sd))*100;
    }
  }

} // end namespace


#endif /* Include guard */
